# -*- coding: utf-8 -*-
import json
from datetime import datetime

import requests

from common.log import logger_1, logger_2, logger_3, logger_4, logger_5
from config import conf
from version_information import CURRENT_VERSION_NUMBER


class WooXinAi:
    def __init__(self, index):
        self.address = conf().get("address")
        self.base_url = self.address + "/api/wx/{}"

        self.index = index

        self.logger = None
        self.logger_choose(self.index)

        if self.index == 1:
            self.user_key = conf().get("KEY_1")
        elif self.index == 2:
            self.user_key = conf().get("KEY_2")
        elif self.index == 3:
            self.user_key = conf().get("KEY_3")
        elif self.index == 4:
            self.user_key = conf().get("KEY_4")
        elif self.index == 5:
            self.user_key = conf().get("KEY_5")

        self.token = ""
        self.reply_content = ""  # 存储API回复内容
        self.token_obtained = False  # 表示token是否已获取
        self.assistant_logged_in = False  # 表示助手是否已登录
        self.friends_synchronized = False
        self.assistant_id = None

        self.channel = conf().get("channel")

        self.uin = None
        self.user_name = None
        self.nick_name = None
        self.remark_name = None
        self.sex = None
        self.province = None
        self.city = None
        self.attr_status = None
        self.seq = None
        self.member_list = None

        self.retry_count = 0  # 添加重试计数器

        self.LOGOUT = False  # 当前状态，确保只向后端发送一次登出信息

    def logger_choose(self, index):
        if index == 1:
            self.logger = logger_1
        elif index == 2:
            self.logger = logger_2
        elif index == 3:
            self.logger = logger_3
        elif index == 4:
            self.logger = logger_4
        elif index == 5:
            self.logger = logger_5

    def getToken(self):
        """
        认证登录
        Returns:

        """
        if not self.token_obtained:  # 只有当token未获取时才执行获取操作
            url = self.base_url.format("auth") + "?a_key=" + self.user_key
            payload = {}
            headers = {
                'User-Agent': 'Apifox/1.0.0 (https://apifox.com)'
            }
            try:
                response = requests.request("GET", url, headers=headers, data=payload, timeout=10)
                response.raise_for_status()
                parsed_json = json.loads(response.text)
                # 获取"data"键下的"token"值
                if 'token' in parsed_json['data']:
                    token_value = parsed_json['data']['token']
                    self.token = token_value
                    self.token_obtained = True  # 标记token已获取
                    return True
                else:
                    self.logger.info("获取token出错:{}".format(parsed_json['msg']))
                    return parsed_json['msg']
            except requests.exceptions.RequestException as e:
                self.logger.error("获取token出错: %s", e)

    def assistant_login(self, uin, user_name, nick_name, remark_name, sex, province, city, attr_status, seq, mac):
        """
        助手上线通知
        Args:
            uin:
            user_name:
            nick_name:
            remark_name:
            sex:
            province:
            city:
            attr_status:
            seq:
        """
        self.uin = uin
        self.user_name = user_name
        self.nick_name = nick_name
        self.remark_name = remark_name
        self.sex = sex
        self.province = province
        self.city = city
        self.attr_status = attr_status
        self.seq = seq
        self.mac = mac

        if not self.assistant_logged_in:  # 只有当助手未登录时才执行登录操作
            url = self.base_url.format("assistant_login")
            headers = {
                'token': self.token,
                'User-Agent': 'Apifox/1.0.0 (https://apifox.com)',
                'Content-Type': 'application/json'
            }
            user = json.dumps({
                "Uin": uin,
                "UserName": user_name,
                "NickName": nick_name,
                "RemarkName": remark_name,
                "Sex": sex,
                "Province": province,
                "City": city,
                "AttrStatus": attr_status,
                "seq": seq,
                "channel": self.channel,
                "version": CURRENT_VERSION_NUMBER,
                "mac": self.mac
            })
            try:
                # print(user)
                response = requests.request("POST", url, headers=headers, data=user, timeout=10)
                parsed_json = json.loads(response.text)
                if 'assistant_id' not in parsed_json['data']:
                    return parsed_json['msg']
                try:
                    self.assistant_id = json.loads(response.text)["data"]["assistant_id"]
                    self.logger.info("助手ID: %s", self.assistant_id)
                except json.decoder.JSONDecodeError as e:
                    self.logger.error("json解析错误: %s", e)
                self.logger.info("助手已上线")
                self.assistant_logged_in = True  # 标记助手已登录
                self.LOGOUT = False
                return None
            except requests.exceptions.RequestException as e:
                self.logger.error("Error logging in assistant: %s", e)

    def friends_syn(self, uin, user_name, member_list):
        """
        同步助手好友
        Args:
            uin:微信登录用户的uin
            member_list:好友列表
        """
        self.user_name = user_name
        self.member_list = member_list
        # if not self.friends_synchronized:
        url = self.base_url.format("syn_friends")
        headers = {
            'token': self.token,
            'User-Agent': 'Apifox/1.0.0 (https://apifox.com)',
            'Content-Type': 'application/json'
        }
        friends = json.dumps({
            "Uin": uin,
            "UserName": user_name,
            "assistant_id": self.assistant_id,
            "MemberList": member_list
        })
        try:
            response = requests.request("POST", url, headers=headers, data=friends, timeout=10)
            response.raise_for_status()
        except requests.exceptions.HTTPError as http_err:
            error_info = f"HTTP 错误: {http_err}"
            self.logger.error(error_info)
            self.syn_runlog(error_info)
        except requests.exceptions.ConnectionError as conn_err:
            error_info = f"连接错误: {conn_err}"
            self.logger.error(error_info)
            self.syn_runlog(error_info)
        except requests.exceptions.Timeout as timeout_err:
            error_info = f"请求超时: {timeout_err}"
            self.logger.error(error_info)
            self.syn_runlog(error_info)
        except requests.exceptions.RequestException as req_err:
            error_info = f"请求异常: {req_err}"
            self.logger.error(error_info)
            self.syn_runlog(error_info)
        except ValueError as json_err:
            error_info = f"JSON 解析错误: {json_err}"
            self.logger.error(error_info)
            self.syn_runlog(error_info)
        except Exception as e:
            error_info = f"未知错误: {e}"
            self.logger.error(error_info)
            self.syn_runlog(error_info)

    def syn_remark(self):
        """
        同步助手好友备注，拉取后端的备注信息，
        """
        url = self.base_url.format("syn_remark")
        headers = {
            'token': self.token,
            'User-Agent': 'Apifox/1.0.0 (https://apifox.com)',
            'Content-Type': 'application/json'
        }
        body = json.dumps({
            "assistant_id": self.assistant_id
        })
        try:
            response = requests.request("POST", url, headers=headers, data=body, timeout=10)
            response.raise_for_status()
            reply_content = response.text
            reply_content = json.loads(reply_content)
            reply_content = reply_content['data']
            return reply_content
        except requests.exceptions.HTTPError as http_err:
            error_info = f"HTTP 错误: {http_err}"
            self.logger.error(error_info)
            self.syn_runlog(error_info)
        except requests.exceptions.ConnectionError as conn_err:
            error_info = f"连接错误: {conn_err}"
            self.logger.error(error_info)
            self.syn_runlog(error_info)
        except requests.exceptions.Timeout as timeout_err:
            error_info = f"请求超时: {timeout_err}"
            self.logger.error(error_info)
            self.syn_runlog(error_info)
        except requests.exceptions.RequestException as req_err:
            error_info = f"请求异常: {req_err}"
            self.logger.error(error_info)
            self.syn_runlog(error_info)
        except ValueError as json_err:
            error_info = f"JSON 解析错误: {json_err}"
            self.logger.error(error_info)
            self.syn_runlog(error_info)
        except Exception as e:
            error_info = f"未知错误: {e}"
            self.logger.error(error_info)
            self.syn_runlog(error_info)

    def group_syn(self, group_list):
        """
        同步群信息
        Args:
            group_list:群列表
        """
        self.group_list = group_list
        # if not self.friends_synchronized:
        url = self.base_url.format("syn_group")
        headers = {
            'token': self.token,
            'User-Agent': 'Apifox/1.0.0 (https://apifox.com)',
            'Content-Type': 'application/json'
        }
        groups = json.dumps({
            "assistant_id": self.assistant_id,
            "groupList": group_list
        })
        try:
            response = requests.request("POST", url, headers=headers, data=groups, timeout=10)
            response.raise_for_status()
        except requests.exceptions.HTTPError as http_err:
            error_info = f"HTTP 错误: {http_err}"
            self.logger.error(error_info)
            self.syn_runlog(error_info)
        except requests.exceptions.ConnectionError as conn_err:
            error_info = f"连接错误: {conn_err}"
            self.logger.error(error_info)
            self.syn_runlog(error_info)
        except requests.exceptions.Timeout as timeout_err:
            error_info = f"请求超时: {timeout_err}"
            self.logger.error(error_info)
            self.syn_runlog(error_info)
        except requests.exceptions.RequestException as req_err:
            error_info = f"请求异常: {req_err}"
            self.logger.error(error_info)
            self.syn_runlog(error_info)
        except ValueError as json_err:
            error_info = f"JSON 解析错误: {json_err}"
            self.logger.error(error_info)
            self.syn_runlog(error_info)
        except Exception as e:
            error_info = f"未知错误: {e}"
            self.logger.error(error_info)
            self.syn_runlog(error_info)

    def sendAndReceive(self, message, from_user_name, to_user_name, msg_type, file_name):
        """
        发起聊天
        Args:
            message:文本信息内容
            from_user_name:微信用户
            msg_type:0或空为文本,1为单张图片,2为语音
            file_name: 图片或语音的文件名
        将回复的消息存入self.reply_content
        """

        # 发送图片或语音文件
        file = ""
        if msg_type == 1 or msg_type == 2:
            message = ""
            with open(file_name, "rb") as f:
                file_content = f.read()
                file = {
                    "file": file_content
                }
        # print(file)
        url = self.base_url.format("chat")
        body = {
            "msg": message,
            "assistant_id": self.assistant_id,
            "FromUserName": from_user_name,
            "ToUserName": to_user_name,
            "type": msg_type
        }
        headers = {
            'token': self.token,
            'User-Agent': 'Apifox/1.0.0 (https://apifox.com)'
        }
        # print(body)
        try:
            response = requests.request("POST", url, headers=headers, data=body, files=file, timeout=10)
            response.raise_for_status()
            reply_content = self.text_get(response.text, message, from_user_name, to_user_name, msg_type, file_name)
            if reply_content is not None:
                self.reply_content = reply_content
            else:
                pass  # error时进入递归调用，为None时不做任何操作
        except requests.exceptions.HTTPError as http_err:
            error_info = f"HTTP 错误: {http_err}"
            self.logger.error(error_info)
            self.syn_runlog(error_info)
            self.reply_content = ""
        except requests.exceptions.ConnectionError as conn_err:
            error_info = f"连接错误: {conn_err}"
            self.logger.error(error_info)
            self.syn_runlog(error_info)
            self.reply_content = ""
        except requests.exceptions.Timeout as timeout_err:
            error_info = f"请求超时: {timeout_err}"
            self.logger.error(error_info)
            self.syn_runlog(error_info)
            self.reply_content = ""
        except requests.exceptions.RequestException as req_err:
            error_info = f"请求异常: {req_err}"
            self.logger.error(error_info)
            self.syn_runlog(error_info)
            self.reply_content = ""
        except ValueError as json_err:
            error_info = f"JSON 解析错误: {json_err}"
            self.logger.error(error_info)
            self.syn_runlog(error_info)
            self.reply_content = ""
        except Exception as e:
            error_info = f"未知错误: {e}"
            self.logger.error(error_info)
            self.syn_runlog(error_info)
            self.reply_content = ""

    def sendAndReceive_group(self, message, group_user_name, from_user_name, to_user_name, msg_type, file_name,
                             is_at=False):
        """
        发起聊天
        Args:
            message:文本信息内容
            from_user_name:微信用户
            msg_type:0或空为文本,1为单张图片,2为语音
            file_name: 图片或语音的文件名
        将回复的消息存入self.reply_content
        """

        # 发送图片或语音文件
        file = ""
        if msg_type == 1 or msg_type == 2:
            message = ""
            with open(file_name, "rb") as f:
                file_content = f.read()
                file = {
                    "file": file_content
                }
        url = self.base_url.format("group_chat")
        body = {
            "msg": message,
            "assistant_id": self.assistant_id,
            "GroupUserName": group_user_name,
            "FromUserName": from_user_name,
            "IsAt": is_at,
            "type": msg_type
        }
        headers = {
            'token': self.token,
            'User-Agent': 'Apifox/1.0.0 (https://apifox.com)'
        }
        try:
            response = requests.request("POST", url, headers=headers, data=body, files=file, timeout=10)
            response.raise_for_status()
            reply_content = self.text_get(response.text, message, from_user_name, to_user_name, msg_type, file_name,
                                          is_group=True,
                                          group_user_name=group_user_name)
            if reply_content is not None:
                self.reply_content = reply_content
            else:
                pass  # error时进入递归调用，为None时不做任何操作
        except requests.exceptions.HTTPError as http_err:
            error_info = f"HTTP 错误: {http_err}"
            self.logger.error(error_info)
            self.syn_runlog(error_info)
            self.reply_content = ""
        except requests.exceptions.ConnectionError as conn_err:
            error_info = f"连接错误: {conn_err}"
            self.logger.error(error_info)
            self.syn_runlog(error_info)
            self.reply_content = ""
        except requests.exceptions.Timeout as timeout_err:
            error_info = f"请求超时: {timeout_err}"
            self.logger.error(error_info)
            self.syn_runlog(error_info)
            self.reply_content = ""
        except requests.exceptions.RequestException as req_err:
            error_info = f"请求异常: {req_err}"
            self.logger.error(error_info)
            self.syn_runlog(error_info)
            self.reply_content = ""
        except ValueError as json_err:
            error_info = f"JSON 解析错误: {json_err}"
            self.logger.error(error_info)
            self.syn_runlog(error_info)
            self.reply_content = ""
        except Exception as e:
            error_info = f"未知错误: {e}"
            self.logger.error(error_info)
            self.syn_runlog(error_info)
            self.reply_content = ""

    def message_pull(self, type):
        """
        拉取主动消息
        """
        url = self.base_url.format("notice")
        body = json.dumps({
            "assistant_id": self.assistant_id,
            "type": type
        })
        headers = {
            'token': self.token,
            'User-Agent': 'Apifox/1.0.0 (https://apifox.com)',
            'Content-Type': 'application/json'
        }
        """
        获取的消息目前有三种：
        1意向用户 全天
        2招呼语   在指定时段发送如9~18
        3追加话术 全天
        """
        try:
            response = requests.request("POST", url, headers=headers, data=body, timeout=10)
            response.raise_for_status()  # 如果响应状态码不是200，抛出HTTPError异常
            data = json.loads(response.text)
            msg_list = [{"id": item["id"], "UserName": item["UserName"],
                         "msg": item["msg"].replace('\\\\n', '\n').replace('\\\n', '\n').replace('\\n', '\n')} for item
                        in data["data"]]
            return msg_list
        except requests.exceptions.HTTPError as http_err:
            error_info = f"HTTP 错误: {http_err}"
            self.logger.error(error_info)
            self.syn_runlog(error_info)
        except requests.exceptions.ConnectionError as conn_err:
            error_info = f"连接错误: {conn_err}"
            self.logger.error(error_info)
            self.syn_runlog(error_info)
        except requests.exceptions.Timeout as timeout_err:
            error_info = f"请求超时: {timeout_err}"
            self.logger.error(error_info)
            self.syn_runlog(error_info)
        except requests.exceptions.RequestException as req_err:
            error_info = f"请求异常: {req_err}"
            self.logger.error(error_info)
            self.syn_runlog(error_info)
        except ValueError as json_err:
            error_info = f"JSON 解析错误: {json_err}"
            self.logger.error(error_info)
            self.syn_runlog(error_info)
        except Exception as e:
            error_info = f"未知错误: {e}"
            self.logger.error(error_info)
            self.syn_runlog(error_info)

    def message_pull_receipt(self, id):
        """
        发送主动消息回执
        """
        url = self.base_url.format("notice_receipt")
        body = json.dumps({
            "notice_id": id
        })
        headers = {
            'token': self.token,
            'User-Agent': 'Apifox/1.0.0 (https://apifox.com)',
            'Content-Type': 'application/json'
        }
        try:
            response = requests.request("POST", url, headers=headers, data=body, timeout=10)
            response.raise_for_status()
            self.logger.info("已发送回执")
        except requests.exceptions.HTTPError as http_err:
            error_info = f"HTTP 错误: {http_err}"
            self.logger.error(error_info)
            self.syn_runlog(error_info)
        except requests.exceptions.ConnectionError as conn_err:
            error_info = f"连接错误: {conn_err}"
            self.logger.error(error_info)
            self.syn_runlog(error_info)
        except requests.exceptions.Timeout as timeout_err:
            error_info = f"请求超时: {timeout_err}"
            self.logger.error(error_info)
            self.syn_runlog(error_info)
        except requests.exceptions.RequestException as req_err:
            error_info = f"请求异常: {req_err}"
            self.logger.error(error_info)
            self.syn_runlog(error_info)
        except ValueError as json_err:
            error_info = f"JSON 解析错误: {json_err}"
            self.logger.error(error_info)
            self.syn_runlog(error_info)
        except Exception as e:
            error_info = f"未知错误: {e}"
            self.logger.error(error_info)
            self.syn_runlog(error_info)

    def log_out(self, is_time=False):
        """
        向后端发送登出信息
        """
        url = self.base_url.format("login_out")
        headers = {
            'token': self.token,
            'User-Agent': 'Apifox/1.0.0 (https://apifox.com)',
            'Content-Type': 'application/json'
        }
        if is_time:
            time = datetime.now()
            body = json.dumps({
                "assistant_id": self.assistant_id,
                "time": time.strftime("%Y-%m-%d %H:%M:%S")
            })
        else:
            body = json.dumps({
                "assistant_id": self.assistant_id,
                "time": None
            })
        if self.LOGOUT:
            return
        else:
            try:
                response = requests.request("POST", url, headers=headers, data=body, timeout=10)
                self.logger.info("已发送登出信息")
                self.LOGOUT = True
            except requests.exceptions.RequestException as e:
                self.logger.error("发送登出信息出错: %s", e)

    def syn_runlog(self, log):
        """
        向后端发送日志信息
        """
        url = self.base_url.format("syn_runlog")
        headers = {
            'token': self.token,
            'User-Agent': 'Apifox/1.0.0 (https://apifox.com)',
            'Content-Type': 'application/json'
        }
        body = json.dumps({
            "assistant_id": self.assistant_id,
            "log": log
        })
        try:
            response = requests.request("POST", url, headers=headers, data=body, timeout=10)
            self.logger.info("已发送日志信息")
        except requests.exceptions.RequestException as e:
            self.logger.error("发送日志信息出错: %s", e)

    def process_wechat_message(self, message, from_user_name, to_user_name, msg_type=0, file_name="", is_group=False,
                               group_user_name=None, is_at=False):
        """
        处理微信消息，调用sendAndReceive并返回要回复的消息
        """
        if is_group:
            self.sendAndReceive_group(message, group_user_name, from_user_name, to_user_name, msg_type, file_name,
                                      is_at)
        else:
            self.sendAndReceive(message, from_user_name, to_user_name, msg_type, file_name)
        return self.reply_content

    def re_login(self):
        """掉线时,尝试重新登录"""
        self.assistant_login(self.uin, self.user_name, self.nick_name, self.remark_name, self.sex, self.province,
                             self.city, self.attr_status, self.seq, self.mac)
        self.friends_syn(self.uin, self.user_name, self.member_list)
        self.logger.info("助手登录成功")

    def text_get(self, stream, message, from_user_name, to_user_name, msg_type, file_name, is_group=False,
                 group_user_name=None):
        """
        信息流处理,将信息流转换为文本
        Args:
            to_user_name:
            file_name:
            msg_type:
            from_user_name:
            message:
            stream:初始的信息流数据
        Returns:
            处理后的原始文本

        """
        try:
            # print(stream)
            data_stream = stream
            # 检查数据流是否为空或不包含"data:"，如果是则记录日志并返回空字符串
            if not data_stream or "data" not in data_stream:
                parsed_data = json.loads(data_stream)
                msg_value = parsed_data['msg']
                if msg_value == "登录超时，请重新登录":
                    self.logger.info("助手掉线,尝试重新登录中......")
                    self.re_login()
                    self.sendAndReceive(message, from_user_name, to_user_name, msg_type, file_name)
                    return
                else:
                    self.logger.info("数据流为空或不包含'data'：{}".format(data_stream))
                    return "".lstrip()
            events = data_stream.split("\n")
            events = [element for element in events if element != '' and element is not None]
            event = events[-1]
        except json.JSONDecodeError as e:
            self.logger.error("JSON解析错误: %s, 数据流: %s", e, data_stream)
        except IndexError as e:
            self.logger.error("索引错误: %s, 事件列表: %s", e, events)
        except Exception as e:
            self.logger.error("处理文本时发生错误: %s, 数据流: %s, 事件列表: %s", e, data_stream, events)


        try:
            # print(event)
            # 如果event以data:开头，则去掉开头的data:
            if event.startswith("data:"):
                event = event[len("data:"):].strip()
            # print(event)
            event_dict = json.loads(event)
            if 'msg' in event_dict and 'reply' in event_dict['data']:  # 有回复信息， 为正常回复或error
                reply_content = event_dict['data']['reply']
            elif 'msg' in event_dict and 'reply' not in event_dict['data']:  # 无回复信息
                self.logger.info(event_dict['msg'])
                return ""
            elif 'msg' not in event_dict and 'event' in event_dict and event_dict['event'] == "error":
                reply_content = "error"
            else:
                return ""

            if reply_content == "error" or reply_content == "Undefined array key 0":  # 错误回复则再次调用接口
                if self.retry_count < 3:
                    self.retry_count += 1
                    self.logger.info("发生异常, 重新询问AI, 重试次数: %d", self.retry_count)
                    if is_group:
                        self.sendAndReceive_group(message, group_user_name, from_user_name, msg_type, file_name)
                    elif not is_group:
                        self.sendAndReceive(message, from_user_name, to_user_name, msg_type, file_name)
                    return
                else:
                    self.logger.info("达到最大重试次数，不再重新询问AI")
                    self.reply_content = ""
                    self.retry_count = 0  # 重置次数
                    return ""
            else:  # 正确回复直接转发
                reply_content = reply_content.replace('\\\\n', '\n').replace('\\\n', '\n').replace('\\n', '\n')
                self.retry_count = 0  # 重置次数
                return reply_content

        except json.JSONDecodeError as e:
            if event == "</html>":  # php报错的情况
                self.logger.error("php发生报错")
                pass
            else:
                self.logger.error("解析json出错: {}，{}".format(event, e))
            self.reply_content = ""
            return ""
            # if self.retry_count < 3:
            #         self.retry_count += 1
            #         self.logger.info("AI回复格式错误, 重新询问AI, 重试次数: %d", self.retry_count)
            #         if is_group:
            #             self.sendAndReceive_group(message, group_user_name, from_user_name, msg_type, file_name)
            #         elif not is_group:
            #             self.sendAndReceive(message, from_user_name, msg_type, file_name)
            #         return
            # else:
            #     self.logger.info("达到最大重试次数，不再重新询问AI")
            #     self.reply_content = ""
            #     self.retry_count = 0  # 重置次数
            #     return ""
